package com.yangxk.kadmin.web.module.sample.service.impl;

import com.yangxk.kadmin.common.base.AbstractService;
import com.yangxk.kadmin.common.support.generator.IdGenerator;
import com.yangxk.kadmin.common.exception.BizException;
import com.yangxk.kadmin.common.exception.ParamException;
import com.yangxk.kadmin.common.util.ValidUtil;
import com.yangxk.kadmin.web.common.Const;
import com.yangxk.kadmin.web.common.enumeration.ResponseCode;
import com.yangxk.kadmin.web.module.sample.form.AreaEditForm;
import com.yangxk.kadmin.web.module.sample.mapper.AreaMapper;
import com.yangxk.kadmin.web.module.sample.po.Area;
import com.yangxk.kadmin.web.module.sample.vo.AreaVo;
import com.yangxk.kadmin.web.module.sample.service.AreaService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.yangxk.kadmin.common.support.BeanValidator;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class AreaServiceImpl extends AbstractService<Area, Long> implements AreaService {

    @Autowired
    private AreaMapper areaMapper;

    @Override
    public List<AreaVo> queryAreaTree() {
        List<Area> list = areaMapper.queryAll();
        return transform2Tree(list, Const.TREE_ROOT_PARENTID);
    }

    @Transactional
    @Override
    public long addArea(AreaEditForm form) {
        BeanValidator.check(form);
        Area area = new Area();
        BeanUtils.copyProperties(form, area);

        area.setId(IdGenerator.getId());
        // TODO 设置创建 更新时间
        areaMapper.insertSelective(area);

        return area.getId();
    }

    @Override
    @Transactional
    public long updateArea(AreaEditForm updateForm) {
        BeanValidator.check(updateForm);

        if (updateForm.getId() == null)
            throw new ParamException("id不能为空");

        Area area = areaMapper.selectByPrimaryKey(updateForm.getId());
        if (area == null)
            throw new BizException(ResponseCode.UPDATE_CHECK_NULL);

        Area update = new Area();
        BeanUtils.copyProperties(updateForm, update);
        // TODO 设置更新时间

        areaMapper.updateByPrimaryKeySelective(update);
        return area.getId();
    }

    @Override
    @Transactional
    public void deleteArea(long id) {
        Area area = areaMapper.selectByPrimaryKey(id);
        if (area == null)
            throw new BizException(ResponseCode.UPDATE_CHECK_NULL);

        List<Area> areas = recursiveQuery(id);

        Set<Long> ids = areas.stream().map(Area::getId).collect(Collectors.toSet());
        ids.add(id);

    areaMapper.deleteBatch(new ArrayList<>(ids));
    }

    private List<AreaVo> transform2Tree(List<Area> list, long parentId) {
        List<AreaVo> result = new ArrayList<>();
        AreaVo vo = null;
        for (Area po : list) {
            if (parentId == po.getParentId()) {
                vo = new AreaVo();
                BeanUtils.copyProperties(po, vo);

                // 递归寻找子节点
                vo.setChildren(transform2Tree(list, po.getId()));

                result.add(vo);
            }
        }

        return result;
    }
    private List<Area> recursiveQuery(long parentId) {
        List<Area> result = new ArrayList<>();

        List<Area> areas = areaMapper.queryByParentId(parentId);
        result.addAll(areas);
        if (!ValidUtil.isEmpty(areas)) {
            for (Area area : areas) {
                List<Area> childs = recursiveQuery(area.getId());
                    result.addAll(childs);
            }
        }

        return result;
    }
}
